home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.8 / effect.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-16  |  18.6 KB  |  585 lines

  1. #include "effect.h"
  2. #include "particles.h"
  3.  
  4. //Global Effect variables
  5. ID3DXMesh *billboardMesh = NULL;
  6. D3DMATERIAL9 whiteMtrl;
  7. SHADER effectVertexShader, effectPixelShader, fireVertexShader, firePixelShader;
  8. D3DXHANDLE effectMatW, effectMatVP, effectVCol;
  9. D3DXHANDLE fireMatW, fireMatVP, fireTime, fireOffset, fireDirToCam;
  10. ID3DXSprite *sprite = NULL;
  11.  
  12. //Global Effect Textures
  13. IDirect3DTexture9* runesTexture = NULL;
  14. IDirect3DTexture9* cloudTexture = NULL;
  15. IDirect3DTexture9* fireballTexture = NULL;
  16. IDirect3DTexture9* lensflareTexture = NULL;
  17. IDirect3DTexture9* noiseTexture = NULL;
  18. IDirect3DTexture9* fireTexture = NULL;
  19.  
  20. //Effect Pool
  21. std::vector<EFFECT*> effects;
  22.  
  23. struct SimpleVertex
  24. {
  25.     SimpleVertex(){}
  26.     SimpleVertex(D3DXVECTOR3 pos, D3DXVECTOR3 norm, D3DXVECTOR2 _uv)
  27.     {
  28.         position = pos;
  29.         normal = norm;
  30.         uv = _uv;
  31.     }
  32.  
  33.     D3DXVECTOR3 position, normal;
  34.     D3DXVECTOR2 uv;
  35.  
  36.     static const DWORD FVF;
  37. };
  38.  
  39. const DWORD SimpleVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
  40.  
  41. void LoadEffectResources(IDirect3DDevice9 *m_pDevice)
  42. {
  43.     //Calculate sight mesh (a simple quad)
  44.     D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, SimpleVertex::FVF, m_pDevice, &billboardMesh);
  45.  
  46.     //Create 4 vertices
  47.     SimpleVertex* v = 0;
  48.     billboardMesh->LockVertexBuffer(0,(void**)&v);
  49.     v[0] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 0));
  50.     v[1] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 0));
  51.     v[2] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 1));
  52.     v[3] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 1));
  53.     billboardMesh->UnlockVertexBuffer();
  54.  
  55.     //Create 2 faces
  56.     WORD* indices = 0;
  57.     billboardMesh->LockIndexBuffer(0,(void**)&indices);    
  58.     indices[0] = 0; indices[1] = 1; indices[2] = 2;
  59.     indices[3] = 1; indices[4] = 3; indices[5] = 2;
  60.     billboardMesh->UnlockIndexBuffer();
  61.  
  62.     //Set Attributes for the 2 faces
  63.     DWORD *att = 0;
  64.     billboardMesh->LockAttributeBuffer(0,&att);
  65.     att[0] = 0; att[1] = 0;
  66.     billboardMesh->UnlockAttributeBuffer();
  67.  
  68.     //Sight MTRL
  69.     memset(&whiteMtrl, 0, sizeof(D3DMATERIAL9));
  70.     whiteMtrl.Diffuse = whiteMtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  71.  
  72.     //Load Shaders
  73.     effectVertexShader.Init(m_pDevice, "shaders/effect.vs", VERTEX_SHADER);
  74.     effectPixelShader.Init(m_pDevice, "shaders/effect.ps", PIXEL_SHADER);
  75.     fireVertexShader.Init(m_pDevice, "shaders/fire.vs", VERTEX_SHADER);
  76.     firePixelShader.Init(m_pDevice, "shaders/fire.ps", PIXEL_SHADER);
  77.  
  78.     //Get constants
  79.     effectMatW = effectVertexShader.GetConstant("matW");
  80.     effectMatVP = effectVertexShader.GetConstant("matVP");
  81.     effectVCol = effectVertexShader.GetConstant("vertexColor");
  82.     fireMatW = fireVertexShader.GetConstant("matW");
  83.     fireMatVP = fireVertexShader.GetConstant("matVP");
  84.     fireTime = fireVertexShader.GetConstant("time");
  85.     fireOffset = fireVertexShader.GetConstant("offset");
  86.     fireDirToCam = fireVertexShader.GetConstant("DirToCam");
  87.  
  88.     //Create Sprite
  89.     D3DXCreateSprite(m_pDevice, &sprite);
  90.  
  91.     //Load textures
  92.     D3DXCreateTextureFromFile(m_pDevice, "textures/runes.dds", &runesTexture);
  93.     D3DXCreateTextureFromFile(m_pDevice, "textures/cloud.dds", &cloudTexture);
  94.     D3DXCreateTextureFromFile(m_pDevice, "textures/fireball.dds", &fireballTexture);
  95.     D3DXCreateTextureFromFile(m_pDevice, "textures/lensflare.dds", &lensflareTexture);
  96.     D3DXCreateTextureFromFile(m_pDevice, "textures/noise.dds", &noiseTexture);
  97.     D3DXCreateTextureFromFile(m_pDevice, "textures/fire.dds", &fireTexture);
  98. }
  99.  
  100. void UnloadEffectResources()
  101. {
  102.     if(billboardMesh)billboardMesh->Release();
  103.     billboardMesh = NULL;
  104.  
  105.     if(sprite)sprite->Release();
  106.     sprite = NULL;
  107.  
  108.     //Release textures
  109.     if(runesTexture)runesTexture->Release();
  110.     if(cloudTexture)cloudTexture->Release();
  111.     if(fireballTexture)fireballTexture->Release();
  112.     if(lensflareTexture)lensflareTexture->Release();
  113.     if(noiseTexture)noiseTexture->Release();
  114.     if(fireTexture)fireTexture->Release();
  115.  
  116.     runesTexture = NULL;
  117.     cloudTexture = NULL;
  118.     fireballTexture = NULL;
  119.     lensflareTexture = NULL;
  120.     noiseTexture = NULL;
  121.     fireTexture = NULL;
  122. }
  123.  
  124. //////////////////////////////////////////////////////////////////////////////////////////////
  125. //                                TRANSFORM                                                    //
  126. //////////////////////////////////////////////////////////////////////////////////////////////
  127.  
  128. TRANSFORM::TRANSFORM(){ m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  129. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  130. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  131. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  132.  
  133. void TRANSFORM::Init(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  134. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  135. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  136.  
  137. D3DXMATRIX TRANSFORM::GetWorldMatrix()
  138. {
  139.     D3DXMATRIX p, r, s;
  140.     D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
  141.     D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
  142.     D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
  143.     D3DXMATRIX world = s * r * p;
  144.     return world;
  145. }
  146.  
  147. //////////////////////////////////////////////////////////////////////////////////////////////
  148. //                                EFFECTS    BASE CLASS                                            //
  149. //////////////////////////////////////////////////////////////////////////////////////////////
  150.  
  151. EFFECT::EFFECT(IDirect3DDevice9 *Dev)
  152. {
  153.     m_pDevice = Dev;
  154.     m_time = 0.0f;
  155.     m_color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);    //White
  156. }
  157.  
  158. void EFFECT::PreRender()
  159. {
  160.     //Enable alpha blending
  161.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  162.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  163.     m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  164.     m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  165.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
  166.     m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  167.     m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  168.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  169.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  170.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  171.  
  172.     //Set vertex shader variables
  173.     D3DXMATRIX view, proj;
  174.     m_pDevice->GetTransform(D3DTS_VIEW, &view);
  175.     m_pDevice->GetTransform(D3DTS_PROJECTION, &proj);
  176.     
  177.     effectVertexShader.SetMatrix(effectMatVP, view * proj);
  178.     effectVertexShader.SetVector4(effectVCol, m_color);
  179.  
  180.     //Set material
  181.     m_pDevice->SetMaterial(&whiteMtrl);
  182.  
  183.     //enable Shaders
  184.     effectVertexShader.Begin();
  185.     effectPixelShader.Begin();
  186. }
  187.  
  188. void EFFECT::PostRender()
  189. {
  190.     //Reset renderstates
  191.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
  192.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  193.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  194.  
  195.     //Disable shaders
  196.     effectVertexShader.End();
  197.     effectPixelShader.End();
  198. }
  199.  
  200. //////////////////////////////////////////////////////////////////////////////////////////////
  201. //                                EFFECTS    SPELL                                                //
  202. //////////////////////////////////////////////////////////////////////////////////////////////
  203.  
  204. EFFECT_SPELL::EFFECT_SPELL(IDirect3DDevice9 *Dev, D3DXVECTOR3 _pos) : EFFECT(Dev), m_t1(_pos, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.1f, 0.1f, 0.1f))
  205. {
  206.     m_t1.m_pos.y += 1.0f;
  207.     m_color = D3DXVECTOR4(rand()%1000 / 1000.0f, rand()%1000 / 1000.0f, rand()%1000 / 1000.0f, 0.0f);
  208.  
  209.     for(int i=0;i<10;i++)
  210.     {
  211.         float angle = i * (D3DX_PI / 5.0f);
  212.             
  213.         m_c[i].Init(_pos + D3DXVECTOR3(cos(angle) * 0.5f, 2.5f, sin(angle) * 0.5f),
  214.                   D3DXVECTOR3(D3DX_PI * 0.5f, angle, 0.0f),
  215.                   D3DXVECTOR3(4.0f, 4.0f, 6.0f));
  216.     }
  217. }
  218.  
  219. void EFFECT_SPELL::Update(float timeDelta)
  220. {
  221.     m_time += timeDelta;
  222.  
  223.     //Update Lower spinning quad...
  224.     m_t1.m_rot.y += timeDelta;
  225.  
  226.     //Update cloud
  227.     for(int i=0;i<10;i++)
  228.         m_c[i].m_rot.y -= timeDelta;
  229.  
  230.     //Update Spinning quad scale
  231.     if(m_time < 1.5f)m_t1.m_sca += D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 4.0f;
  232.     if(m_time > 4.5f)m_t1.m_sca -= D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 4.0f;
  233.  
  234.     //Calculate alpha
  235.     m_color.w = m_t1.m_sca.x / 6.0f;
  236. }
  237.  
  238. void EFFECT_SPELL::Render()
  239. {
  240.     PreRender();
  241.  
  242.     if(billboardMesh)
  243.     {
  244.         //Spinning quad
  245.         m_pDevice->SetTexture(0, runesTexture);
  246.         effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  247.         billboardMesh->DrawSubset(0);
  248.  
  249.         //Cloud
  250.         m_pDevice->SetTexture(0, cloudTexture);
  251.         for(int i=0;i<10;i++)
  252.         {
  253.             effectVertexShader.SetMatrix(effectMatW, m_c[i].GetWorldMatrix());
  254.             billboardMesh->DrawSubset(0);
  255.         }
  256.     }
  257.  
  258.     PostRender();
  259. }
  260.  
  261. bool EFFECT_SPELL::isDead()
  262. {
  263.     return m_t1.m_sca.x < 0.0f;
  264. }
  265.  
  266. //////////////////////////////////////////////////////////////////////////////////////////////
  267. //                                EFFECTS    FIREBALL                                            //
  268. //////////////////////////////////////////////////////////////////////////////////////////////
  269.  
  270. EFFECT_FIREBALL::EFFECT_FIREBALL(IDirect3DDevice9 *Dev, BONE *_src, D3DXVECTOR3 _dest) : EFFECT(Dev)
  271. {
  272.     m_pSrcBone = _src;
  273.     m_dest = _dest;
  274.     m_color.w = 0.01f;
  275.     m_prc = 0.0f;
  276.     m_speed = 22.0f;
  277.  
  278.     if(m_pSrcBone != NULL)
  279.     {
  280.         D3DXMATRIX mat = m_pSrcBone->CombinedTransformationMatrix;        
  281.         m_t1.Init(D3DXVECTOR3(mat(3,0), mat(3, 1), mat(3, 2)), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.1f, 0.1f, 0.1f));
  282.     }
  283. }
  284.  
  285. void EFFECT_FIREBALL::Update(float timeDelta)
  286. {
  287.     m_t1.m_rot += D3DXVECTOR3(0.5f, 0.5f, 0.5f) * timeDelta;
  288.  
  289.     if(m_time < 1.0f && m_pSrcBone != NULL)        //Follow staff
  290.     {
  291.         m_time += timeDelta;
  292.         D3DXMATRIX mat = m_pSrcBone->CombinedTransformationMatrix;
  293.         m_t1.m_pos = D3DXVECTOR3(mat(3,0), mat(3, 1), mat(3, 2));        //Extract position from bone
  294.         m_t1.m_sca = D3DXVECTOR3(1.5f, 1.5f, 1.5f) * m_time;
  295.         m_color.w = m_time;
  296.  
  297.         if(m_time > 1.0f)
  298.         {
  299.             m_color.w = m_time * 0.5f;
  300.             m_origin = m_t1.m_pos;
  301.             m_length = D3DXVec3Length(&(m_origin - m_dest));
  302.         }
  303.     }
  304.     else if(m_prc < 1.0f)        //Fly towards target
  305.     {
  306.         m_prc += (m_speed * timeDelta) / m_length;
  307.         m_t1.m_pos = GetPosition(m_prc);
  308.     }
  309.     else                    //Explode
  310.     {
  311.         m_prc += (m_speed * timeDelta) / m_length;
  312.         m_t1.m_sca += D3DXVECTOR3(5.0f, 5.0f, 5.0f) * timeDelta;
  313.         m_color.w -= timeDelta * 0.5f;
  314.     }
  315. }
  316.  
  317. void EFFECT_FIREBALL::Render()
  318. {
  319.     PreRender();
  320.  
  321.     if(billboardMesh)
  322.     {
  323.         D3DXVECTOR3 orgRot = m_t1.m_rot;
  324.         D3DXVECTOR3 rotations[] = {D3DXVECTOR3(0.0f, 0.0f, 0.0f),
  325.                                    D3DXVECTOR3(D3DX_PI * 0.5f, 0.0f, 0.0f),
  326.                                    D3DXVECTOR3(0.0f, D3DX_PI * 0.5f, 0.0f),
  327.                                    D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)};
  328.  
  329.         D3DXVECTOR3 orgPos = m_t1.m_pos;
  330.         D3DXVECTOR3 positions[] = {m_t1.m_pos, 
  331.                                    GetPosition(m_prc - (1.5f / m_length)),
  332.                                    GetPosition(m_prc - (2.5f / m_length)),
  333.                                    GetPosition(m_prc - (3.25f / m_length)),
  334.                                    GetPosition(m_prc - (4.0f / m_length))};
  335.  
  336.         D3DXVECTOR3 orgSca = m_t1.m_sca;
  337.         D3DXVECTOR3 scales[] = {m_t1.m_sca, 
  338.                                 m_t1.m_sca * 0.8f,
  339.                                 m_t1.m_sca * 0.6f,
  340.                                 m_t1.m_sca * 0.4f,
  341.                                 m_t1.m_sca * 0.2f};
  342.     
  343.         m_pDevice->SetTexture(0, fireballTexture);
  344.         for(int t=0;t<5;t++)
  345.             for(int i=0;i<4;i++)
  346.             {
  347.                 m_t1.m_pos = positions[t];
  348.                 m_t1.m_rot = orgRot + rotations[i];
  349.                 m_t1.m_sca = scales[t];
  350.  
  351.                 effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  352.                 billboardMesh->DrawSubset(0);
  353.             }
  354.  
  355.         m_t1.m_pos = orgPos;
  356.         m_t1.m_rot = orgRot;
  357.         m_t1.m_sca = orgSca;
  358.     }
  359.  
  360.     PostRender();
  361. }
  362.  
  363. bool EFFECT_FIREBALL::isDead()
  364. {
  365.     return m_pSrcBone == NULL || m_color.w < 0.0f;
  366. }
  367.  
  368. D3DXVECTOR3 EFFECT_FIREBALL::GetPosition(float p)
  369. {
  370.     if(p < 0.0f)p = 0.0f;
  371.     if(p > 1.0f)p = 1.0f;
  372.  
  373.     D3DXVECTOR3 m_pos = m_origin * (1.0f - p) + m_dest * p;    //Lerp between origin and dest
  374.     m_pos.y += sin(p * D3DX_PI) * 3.0f;                        //Add Arc
  375.     return m_pos;
  376. }
  377.  
  378. //////////////////////////////////////////////////////////////////////////////////////////////
  379. //                                EFFECTS    LENSFLARE                                            //
  380. //////////////////////////////////////////////////////////////////////////////////////////////
  381.  
  382. EFFECT_LENSFLARE::EFFECT_LENSFLARE(IDirect3DDevice9 *Dev, int _type, D3DXVECTOR3 _position) : EFFECT(Dev)
  383. {
  384.     m_position = _position;
  385.     m_type = _type;
  386.     m_mainAlpha = 0.0f;
  387.     m_inScreen = false;
  388.  
  389.     //Add Flares
  390.     if(m_type == 0)    //Standard flare
  391.     {
  392.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.5f, 0.7f, 0));
  393.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 1.0f, 1.0f, 1));
  394.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 0.5f, 0.5f, 1.0f), 1.5f, 1.3f, 2));
  395.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), -0.5f, 0.8f, 3));
  396.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 0.4f, 1.0f, 4));
  397.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.75f, 1.0f, 5));
  398.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f), 1.8f, 1.2f, 6));
  399.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 2.1f, 0.5f, 4));
  400.     }
  401.     else if(m_type == 1)        //Some other flare etc...
  402.     {
  403.         //setup your own flare here...
  404.     }
  405. }
  406.  
  407. void EFFECT_LENSFLARE::Update(float timeDelta)
  408. {
  409.     if(m_inScreen)
  410.         m_mainAlpha += timeDelta * 3.0f;
  411.     else m_mainAlpha -= timeDelta * 3.0f;
  412.  
  413.     if(m_mainAlpha > 1.0f)m_mainAlpha = 1.0f;
  414.     if(m_mainAlpha < 0.0f)m_mainAlpha = 0.0f;
  415. }
  416.  
  417. void EFFECT_LENSFLARE::Render()
  418. {
  419.     if(sprite == NULL || lensflareTexture == NULL)return;
  420.  
  421.     RECT sourceRectangles[7] = {{0, 0, 128, 128},
  422.                                 {128, 0, 256, 128},
  423.                                 {0, 128, 128, 256},
  424.                                 {128, 128, 192, 192},
  425.                                 {192, 128, 256, 192},
  426.                                 {128, 192, 192, 256},
  427.                                 {192, 192, 256, 256}};
  428.  
  429.     //Calculate screen m_position of light source
  430.     D3DXVECTOR3 screenPos;
  431.     D3DVIEWPORT9 Viewport;
  432.     D3DXMATRIX Projection, View, World;
  433.  
  434.     m_pDevice->GetViewport(&Viewport);
  435.     m_pDevice->GetTransform(D3DTS_VIEW, &View);
  436.     m_pDevice->GetTransform(D3DTS_PROJECTION, &Projection);
  437.     D3DXMatrixIdentity(&World);
  438.     D3DXVec3Project(&screenPos, &m_position, &Viewport, &Projection, &View, &World);
  439.  
  440.     //Get light position and screen center
  441.     D3DVIEWPORT9 v;
  442.     m_pDevice->GetViewport(&v);
  443.  
  444.     //Check that light source is within or without the screen bounds
  445.     if(screenPos.x < 0 || screenPos.x > v.Width ||
  446.        screenPos.y < 0 || screenPos.y > v.Height || screenPos.z > 1.0f)
  447.         m_inScreen = false;
  448.     else m_inScreen = true;
  449.  
  450.     //Lensflares aren't visible so exit function...
  451.     if(m_mainAlpha <= 0.0f)return;
  452.     
  453.     D3DXVECTOR2 lightSource = D3DXVECTOR2(screenPos.x, screenPos.y);
  454.     D3DXVECTOR2 screenCenter = D3DXVECTOR2(v.Width * 0.5f, v.Height * 0.5f);
  455.     D3DXVECTOR2 ray =  screenCenter - lightSource;
  456.  
  457.     //Draw the different flares
  458.     D3DXMATRIX sca;
  459.     sprite->Begin(D3DXSPRITE_ALPHABLEND);
  460.     for(int i=0;i<m_flares.size();i++)
  461.     {
  462.         //Calculate Flare position in screen coordinates
  463.         RECT r = sourceRectangles[m_flares[i].sourceFlare];
  464.         D3DXVECTOR2 offset = D3DXVECTOR2((r.right - r.left) / 2.0f, (r.bottom - r.top) / 2.0f) * m_flares[i].scale;
  465.         D3DXVECTOR2 flarePos = lightSource + ray * m_flares[i].place - offset;
  466.  
  467.         //Scale
  468.         D3DXMatrixScaling(&sca, m_flares[i].scale, m_flares[i].scale, 1.0f);
  469.  
  470.         //Calculate flare alpha
  471.         D3DXCOLOR m_color = m_flares[i].color;
  472.         float alpha = (D3DXVec2Length(&((flarePos + offset) - screenCenter)) + 150.0f) / (float)v.Height;
  473.         if(alpha > 1.0f)alpha = 1.0f;
  474.         m_color.a = alpha * m_mainAlpha;
  475.  
  476.         //Draw Flare
  477.         sprite->SetTransform(&sca);
  478.         sprite->Draw(lensflareTexture, &r, NULL, &D3DXVECTOR3(flarePos.x / m_flares[i].scale, flarePos.y / m_flares[i].scale, 0.0f), m_color);
  479.     }
  480.     sprite->End();
  481.  
  482.     D3DXMatrixIdentity(&sca);
  483.     sprite->SetTransform(&sca);
  484. }
  485.  
  486. bool EFFECT_LENSFLARE::isDead()
  487. {
  488.     return false;
  489. }
  490.  
  491. //////////////////////////////////////////////////////////////////////////////////////////////
  492. //                                EFFECT FIRE                                                    //
  493. //////////////////////////////////////////////////////////////////////////////////////////////
  494.  
  495. EFFECT_FIRE::EFFECT_FIRE(IDirect3DDevice9 *Dev, D3DXVECTOR3 m_pos, D3DXVECTOR3 scale) : EFFECT(Dev)
  496. {
  497.     m_pos.y += scale.z * 0.25f;
  498.     m_t1.Init(m_pos, D3DXVECTOR3(-D3DX_PI * 0.5f, 0.0f, 0.0f), scale);
  499.     m_pSmoke = new SMOKE(m_pDevice, 200, m_pos + D3DXVECTOR3(0.0f, scale.x * 0.4f, 0.0f));
  500. }
  501.  
  502. EFFECT_FIRE::~EFFECT_FIRE()
  503. {
  504.     if(m_pSmoke)delete m_pSmoke;
  505. }
  506.  
  507. void EFFECT_FIRE::Update(float timeDelta)
  508. {
  509.     m_time += timeDelta * 0.34f;
  510.  
  511.     if(m_pSmoke)m_pSmoke->Update(timeDelta);
  512. }
  513.  
  514. void EFFECT_FIRE::Render()
  515. {
  516.     if(billboardMesh == NULL)return;
  517.  
  518.     PreRender();    
  519.  
  520.     m_pDevice->SetTexture(0, fireTexture);
  521.     m_pDevice->SetTexture(1, noiseTexture);
  522.  
  523.     //render billboards
  524.     for(int i=0;i<7;i++)
  525.     {
  526.         m_t1.m_rot.y = m_time * 0.3f + i * D3DX_PI * 0.1428f;
  527.         fireVertexShader.SetMatrix(fireMatW, m_t1.GetWorldMatrix());
  528.         fireVertexShader.SetFloat(fireOffset, m_t1.m_rot.y + m_t1.m_pos.x + m_t1.m_pos.z);
  529.         billboardMesh->DrawSubset(0);
  530.     }
  531.  
  532.     PostRender();
  533.  
  534.     if(m_pSmoke)m_pSmoke->Render();
  535. }
  536.  
  537. bool EFFECT_FIRE::isDead()
  538. {
  539.     return false;
  540. }
  541.  
  542. void EFFECT_FIRE::PreRender()
  543. {
  544.     //Enable alpha blending
  545.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  546.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  547.     m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  548.     m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  549.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
  550.     m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  551.     m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  552.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  553.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  554.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  555.  
  556.     //Set vertex shader variables
  557.     D3DXMATRIX view, proj;
  558.     m_pDevice->GetTransform(D3DTS_VIEW, &view);
  559.     m_pDevice->GetTransform(D3DTS_PROJECTION, &proj);
  560.  
  561.     m_camEye = D3DXVECTOR3(view(0,2), 0.0f, view(2,2));
  562.     D3DXVec3Normalize(&m_camEye, &m_camEye);    
  563.  
  564.     fireVertexShader.SetMatrix(fireMatVP, view * proj);
  565.     fireVertexShader.SetFloat(fireTime, m_time);
  566.     fireVertexShader.SetVector3(fireDirToCam, m_camEye);
  567.  
  568.     //Set material
  569.     m_pDevice->SetMaterial(&whiteMtrl);
  570.  
  571.     //enable Shaders
  572.     fireVertexShader.Begin();
  573.     firePixelShader.Begin();
  574. }
  575.  
  576. void EFFECT_FIRE::PostRender()
  577. {
  578.     //Reset renderstates
  579.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
  580.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  581.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  582.  
  583.     fireVertexShader.End();
  584.     firePixelShader.End();
  585. }